/*
 * CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2.cpp
 *
 *  Created on: 2014. 2. 12.
 *      Author: jjaehuny
 */



#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Battle.h"
#include "../../NLogic/Stamina.h"

#include "../../NResource/Static.h"

namespace ProjectZ { namespace NCommand {

static void ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(User * pUser, int16_t ack, uint32_t roomNumber)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_DUNGEON_PARTY_CREATE_ROOM_V2);
	pUser->Send(pAck);
}

void Command::CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(User * pUser, ::Network::Packet *pPacket)
{
	/*
	 CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2        0x1132
	{
			   u8 u8party_member_num;           /// min 1 , max 2 본인 제외한 값
			   u16 u16dungeon_tid;
			   u8 u8difficulty;
	}

	SC_REQ_DUNGEON_PARTY_CREATE_ROOM_V2        0x1133
	{
			   s16 sAck;                                                               /// ACK_NOT_MAKE_PARTY 방 갯수 초과로 방을 만들 수 없음
			   u32 u32room_number;
	}
	 */



	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("CS_REQ_DUNGEON_PARTY_CREATE_ROOM NULL == pWorld");
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_NO_SPACE, 0);
		return;
	}

	if (false == pUser->EndBattle_afterEffect())
	{
		DEBUGLOG("%s false == pUser->EndBattle_afterEffect()", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_BATTLE_AFTEREFFECT, 0);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("%s pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_NO_SPACE, 0);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("%s pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	int totalRoomCount = 0;
	NLogic::Static::PARTYROOMTREE_V2 & clsPartyRoomTree = NLogic::Static::Instance().GETPARTYROOMTREEV2();
	std::for_each(clsPartyRoomTree.begin(), clsPartyRoomTree.end(), [&](NLogic::Static::PARTYROOMTREE_V2::value_type & pair) {
		NLogic::Static::SPACEVECTOR & spaceVector = pair.second;
		totalRoomCount += spaceVector.size();
	} );

	if (totalRoomCount >= MAX_NEW_PARTY_ROOM)
	{
		DEBUGLOG("%s NLogic::Static::Instance().GETPARTYROOMTREE().size() > MAX_NEW_PARTY_ROOM", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_OVER_PARTY_ROOM_COUNT, 0);
		return;
	}

	NLogic::Space * pNewPartyRoomSpace = NLogic::Static::Instance().GETSPACEPOOL()->NEW();
	if (NULL == pNewPartyRoomSpace)
	{
		DEBUGLOG("%s NULL == pNewPartyRoomSpace", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	NLogic::IndexerNewPartyRoomV2 * pIndexer = NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->NEW();
	if (NULL == pIndexer)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);

		DEBUGLOG("%s NULL == pIndexer", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	PREPARE_PACKET;

	uint8_t u8party_member_num = 0;
	uint16_t u16dungeon_tid = 0;
	uint8_t u8difficulty = 0;

	* pPacket >> u8party_member_num >> u16dungeon_tid >> u8difficulty;

	if (u8difficulty < 0 || u8difficulty > 2)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
		NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

		DEBUGLOG("%s : INVALID DIFFICULTY!! difficulty=%d", __FUNCTION__, u8difficulty);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	if (0 > u8party_member_num || u8party_member_num > 3)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
		NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

		DEBUGLOG("%s 0 > u8party_member_num || u8party_member_num > 3", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	NResource::DungeonData::Flyweight * pFly = NResource::Static::Instance().GetDungeon()->GetFly(pUser->GetCompany(), pUser->GetSaleCode(), u16dungeon_tid);
	if (NULL == pFly)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
		NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

		DEBUGLOG("%s NULL == pFly", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	int level = pUser->GetCharacterInfo().level;
	NResource::DungeonEnterLimitLevel * pDungeonEnterLimitLevel = NResource::Static::Instance().GetDungeonEnterLimitLevel();
	if (NULL == pDungeonEnterLimitLevel)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
		NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	int limitLevel = pDungeonEnterLimitLevel->GetLevel(u16dungeon_tid);
	if (level < limitLevel)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
		NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	// 스태미너 부족 여부 확인
	if (true == NResource::Static::Instance().GetContentsOpenResource()->IsOpen(ContentsOpen::STAMINA_SYSTEM))
	{
		NLogic::Stamina * pStamina = pUser->GetStamina();
		if (NULL == pStamina)
		{
			NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
			NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

			DEBUGLOG("%s : pStamina is NULL", __FUNCTION__);
			ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
			return;
		}

		if (true == pStamina->IsStaminaLack(u8difficulty))
		{
			NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
			NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

			ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_NOT_ENOUGHT_DUNGEON_STAMINA, 0);
			return;
		}
	}

	NLogic::Party * pParty = NLogic::Static::Instance().GETPARTYPOOL()->NEW();
	pParty->Open(pUser);

	NLogic::Space::Data clsData;
	clsData._maxUser = u8party_member_num;
	clsData._table_id = u16dungeon_tid;
	clsData._difficulty = u8difficulty;
	clsData._spaceType = NLogic::Space::SpaceType::NEW_PARTY_ROOM;

	pNewPartyRoomSpace->Open(pUser, clsData);
	pNewPartyRoomSpace->SetIndexerNewPartyRoomV2(pIndexer);
	pNewPartyRoomSpace->SetParty(pParty);

	//NLogic::Static::PARTYROOMTREE & clsPartyRoomTree = NLogic::Static::Instance().GETPARTYROOMTREE();
	auto itrs = clsPartyRoomTree.find( u16dungeon_tid );
	if (itrs == clsPartyRoomTree.end())
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pNewPartyRoomSpace);
		NLogic::Static::Instance().GETINDEXERNEWPARTYROOMV2POOL()->DEL(pIndexer);

		DEBUGLOG("%s itrs == clsPartyRoomTree.end()", __FUNCTION__);
		ACK_CS_REQ_DUNGEON_PARTY_CREATE_ROOM_V2(pUser, ACK_UNKNOWN_ERROR, 0);
		return;
	}

	pWorld->LeaveUser(pUser);
	pNewPartyRoomSpace->EnterUser(pUser);
	pUser->SetEnumState(User::EnumState::INVITE);

	NLogic::Static::SPACEVECTOR & spaceVector = itrs->second;
	spaceVector.push_back(pNewPartyRoomSpace);

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ACK_OK) << static_cast<uint32_t>(pIndexer->GetIndex());
	pAck->MakePacket(CMD_SC_REQ_DUNGEON_PARTY_CREATE_ROOM_V2);
	pUser->Send(pAck);

	pParty->AddInviteUserTree(pUser);
	pUser->SetEnumState(User::EnumState::ACCEPT_WAIT);
}

} /*NCommand*/ } /*ProjectZ*/


